package com.an_yang_gang_yie.an_yang_gang_yie.config;

import com.alibaba.fastjson.JSON;
import com.an_yang_gang_yie.an_yang_gang_yie.annotation.UserLoginToken;
import com.an_yang_gang_yie.an_yang_gang_yie.entity.AjaxResponseBody;
import com.an_yang_gang_yie.an_yang_gang_yie.system.entity.Log;
import com.an_yang_gang_yie.an_yang_gang_yie.system.mapper.AdminUserMapper;
import com.an_yang_gang_yie.an_yang_gang_yie.system.mapper.LogMapper;
import com.an_yang_gang_yie.an_yang_gang_yie.utils.Utils;
import com.auth0.jwt.exceptions.JWTDecodeException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;
import java.util.Map;

/**
 * 身份拦截器
 */
@Configuration
public class AuthenticationInterceptor implements HandlerInterceptor {
    @Autowired
    private AdminUserMapper adminUserMapper;
    @Autowired
    private LogMapper logMapper;
    /**
     *1.boolean preHandle ()：
     * 预处理回调方法,实现处理器的预处理，第三个参数为响应的处理器,自定义Controller,
     * 返回值为true表示继续流程（如调用下一个拦截器或处理器）或者接着执行postHandle()
     * 和afterCompletion()；false表示流程中断，不会继续调用其他的拦截器或处理器，中断执行
     */
    @Override
    public boolean preHandle(HttpServletRequest request,
                             HttpServletResponse response, Object handler) throws JWTDecodeException {

        //登录完成才开始记录 start
        Log log = new Log();
        log.setIp(Utils.getIp(request));//设置ip
        log.setMethod(request.getMethod());//设置请求方法类型
        log.setParameter(JSON.toJSON(request.getParameterMap()).toString());
        log.setUrl(request.getRequestURL().toString());
        String token = request.getHeader("token");// 从 http 请求头中取出 token
        String type = request.getHeader("type");// 从 http 请求头中取出 token
        logMapper.insert(log);
        //登录完成才开始记录 start
        if(token=="" || type != "user" || type!="admin" ){
            /**
             * 当前用户非法登录 这里借用JWTDecodeException 异常统一处理
             */
//            throw new JWTDecodeException("非法登录");
        };
        // 如果不是映射到方法直接通过simple
        if(!(handler instanceof HandlerMethod)){
            return true;
        }
        HandlerMethod handlerMethod=(HandlerMethod)handler;
        Method method=handlerMethod.getMethod();
        //检查是否有UserLoginToken注释，有则跳过认证
        if (method.isAnnotationPresent(UserLoginToken.class)) {
            String s = Utils.verifyToken(token);
            /**
             * 查询当前路由用户登录权限注解是否需要不需要直接返回ture
             */
            UserLoginToken passToken = method.getAnnotation(UserLoginToken.class);
            switch (type){
                case "user":

                    if (passToken.required()) {

                        return true;
                    }
                    break;
                case "admin":

                    if (passToken.required()) {

                        return true;
                    }
                    break;

            }

        }
        /**
         * 如果有值说明token是对的 不报错
         * 每值 报错走异常
         * 有值 无效走异常
         */

        return true;
    }
    /**
     *2.void postHandle()：
     * 后处理回调方法，实现处理器的后处理（DispatcherServlet进行视图返回渲染之前进行调用），
     * 此时我们可以通过modelAndView（模型和视图对象）对模型数据进行处理或对视图进行处理，
     * modelAndView也可能为null。
     */
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

    }

    /**
     * 3.void afterCompletion():
     * 整个请求处理完毕回调方法,该方法也是需要当前对应的Interceptor的preHandle()
     * 的返回值为true时才会执行，也就是在DispatcherServlet渲染了对应的视图之后执行。
     * 用于进行资源清理。整个请求处理完毕回调方法。如性能监控中我们可以在此记录结束时间并输
     * 出消耗时间，还可以进行一些资源清理，类似于try-catch-finally中的finally，
     * 但仅调用处理器执行链中
     * @param request
     * @param response
     * @param handler
     * @param ex
     * @throws Exception
     */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {

    }
}
